// Copyright(c) 2019 - 2020, #Momo
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met :
// 
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and /or other materials provided with the distribution.
// 
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "FrustrumCamera.h"

namespace MxEngine
{
    void FrustrumCamera::SetBounds(float x, float y, float size)
    {
        this->SetZoom(size);
        this->SetProjectionCenter(MakeVector2(x, y));
        this->SetProjectionMatrix(MakeFrustrumMatrix(
            x * this->GetAspectRatio(), (x + size) * this->GetAspectRatio(),
            y, (y + size), this->GetZNear(), this->GetZFar()));
    }

    Vector3 FrustrumCamera::GetBounds() const
    {
        auto v = this->GetProjectionCenter();
        auto s = this->GetZoom();
        return MakeVector3(v.x, v.y, s);
    }

    void FrustrumCamera::SetProjectionForTile(size_t xTile, size_t yTile, size_t tilesPerRow, float totalImageSize)
    {
        float tileSize = totalImageSize / float(tilesPerRow);
        float initialOffsetX = -0.5f * tilesPerRow * tileSize;
        float initialOffsetY = -0.5f * tilesPerRow * tileSize;
        float x = initialOffsetX + xTile * tileSize;
        float y = initialOffsetY + yTile * tileSize;
        this->SetBounds(x, y, tileSize);
    }
}